package v1

import (
	"blog/api/global"
	v1 "blog/api/tools/v1"
	"blog/internal/constx"
	"context"
	"fmt"
	"github.com/go-kratos/kratos/v2/transport/http"
	"io"
	http2 "net/http"
	"time"
)

func _Tools_UploadFile0_HTTP_Handler(srv ToolsHTTPServer) func(ctx http.Context) error {
	return func(ctx http.Context) error {
		var in v1.UploadFileRequest
		req := ctx.Request()
		file, header, err := req.FormFile(constx.FileName)
		if err != nil {
			return err
		}
		defer file.Close()
		in.Filename = header.Filename
		in.Content, err = io.ReadAll(file)
		if err != nil {
			return err
		}
		//if err := ctx.Bind(&in); err != nil {
		//	return err
		//}
		//if err := ctx.BindQuery(&in); err != nil {
		//	return err
		//}
		http.SetOperation(ctx, OperationToolsUploadFile)
		h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
			return srv.UploadFile(ctx, req.(*v1.UploadFileRequest))
		})
		out, err := h(ctx, &in)
		if err != nil {
			return err
		}
		reply := out.(*v1.UploadFileReply)
		return ctx.Result(200, reply)
	}
}

const allowedRefer = "http://blog.gwsee.com/"

func _Tools_Files0_HTTP_Handler(srv ToolsHTTPServer) func(ctx http.Context) error {
	return func(ctx http.Context) error {
		// 传递客户端的条件请求头
		if ifNoneMatch := ctx.Request().Header.Get("If-None-Match"); ifNoneMatch != "" {
			ctx.Response().WriteHeader(http2.StatusNotModified)
			return nil
		}
		var in global.IDStr
		if err := ctx.BindQuery(&in); err != nil {
			return err
		}
		if err := ctx.BindVars(&in); err != nil {
			return err
		}
		if ctx.Request().URL != nil && ctx.Request().URL.RawQuery != "" {
			in.Id = fmt.Sprintf("%v%v%v", in.Id, constx.FileParamSep, ctx.Request().URL.RawQuery)
		}
		http.SetOperation(ctx, OperationToolsFiles)
		h := ctx.Middleware(func(ctx context.Context, req interface{}) (interface{}, error) {
			return srv.Files(ctx, req.(*global.IDStr))
		})
		out, err := h(ctx, &in)
		if err != nil {
			return err
		}
		reply := out.(*v1.FilesResp)
		if !reply.Inner {
			http2.Redirect(ctx.Response(), ctx.Request(), reply.Id, http2.StatusTemporaryRedirect)
			ctx.Done()
			return nil
		}
		// 读取内网文件内容
		req, err := http2.NewRequest(http2.MethodGet, reply.Id, nil)
		if err != nil {
			return err
		}
		req.Header.Set("referer", allowedRefer)
		//http2.DefaultClient.Do()
		resp, err := http2.DefaultClient.Do(req) // http2.Get(reply.Id)
		if err != nil {
			return err
		}
		defer resp.Body.Close()

		// 将 Content-Type 设置为目标响应的 Content-Type
		contentType := resp.Header.Get("Content-Type")
		if contentType == "" {
			contentType = "application/octet-stream"
		}
		ctx.Response().Header().Set("Content-Type", contentType)
		ctx.Response().Header().Set("ETag", in.Id)

		// 添加缓存控制 - 关键修改！
		// 设置强缓存 1 年（31536000 秒）
		ctx.Response().Header().Set("Cache-Control", "public, max-age=31536000, immutable")
		// 设置过期时间
		ctx.Response().Header().Set("Expires", time.Now().AddDate(1, 0, 0).Format(time.RFC1123))

		// 将目标文件流直接拷贝到 ctx.Response()
		_, err = io.Copy(ctx.Response(), resp.Body)
		if err != nil {
			return err
		}

		ctx.Done()
		return nil
	}
}
